#include <bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define rg register
#define pc putchar
#define gc getchar
#define pf printf
#define space pc(' ')
#define enter pc('\n')
#define me(x,y) memset(x,y,sizeof(x))
#define pb push_back
#define FOR(i,k,t,p) for(rg int i(k) ; i <= t ; i += p)
#define ROF(i,k,t,p) for(rg int i(k) ; i >= t ; i -= p)
using namespace std ;
bool s_gnd ;

namespace superio{
    #define getchar my_getchar
    #define putchar my_putchar
    #define puts my_puts
    const int Isize = 1<<22,Osize = 1<<20;
    char ibuf[Isize],obuf[Osize];
    char *p1=ibuf,*p2=ibuf;
    int otop;
    class Oclear{
        public:
            inline void clear() {fwrite(obuf,sizeof(char),otop,stdout);otop=0;}
            ~Oclear() {clear();}
    }oclear;
    inline char getchar() {return p1==p2&&(p2=(p1=ibuf)+fread(ibuf,sizeof(char),sizeof(ibuf),stdin),p1==p2)?EOF:*p1++;}
    inline void putchar(const char c) {obuf[otop++]=c;if(otop==Osize)oclear.clear();}
    inline void puts(const char *s) {while(*s!='\0'){putchar(*s);s++;}putchar('\n');}
    int stk[30],tp;

    inline void read(int &x){
        x =  0 ; int r=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c))x=x*10+(c^48),c=getchar();
        x *= f ;
    }
    inline void print(int x){
        if(x<0){
            putchar('-');
            x = -x;
        }
        do stk[++tp]=x%10,x/=10;while(x);
        while(tp)putchar(stk[tp--]^48);
    }
}
using superio::read;
using superio::print;
using superio::puts;
using superio::getchar;
using superio::putchar;
bool S_GND ;
const int N = 1e3+5 ;
const int M = 2e6+5 ;
int n,m,MOD,q,rl ;
int a[N][N],sum[N],ans[M] ;
struct Node{int l,r,id ;} ;
vector<Node>p[N][N],qu[N],dan[N] ;
struct LL{int l,r,w ;}tr[N<<2] ;
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define w(x) tr[x].w
#define mid (tr[x].l+tr[x].r>>1)
void Build(int x,int le,int ri)
{
    tr[x] = {le,ri} ; if(le == ri) {w(x) = sum[le] ; return ;}
    Build(ls(x),le,mid),Build(rs(x),mid+1,ri),w(x) = w(ls(x))*w(rs(x))%MOD ;// print(w(x)),enter ;
}
int Query(int x,int le,int ri)
{
    if(tr[x].l >= le && tr[x].r <= ri) return w(x) ; int res = 1 ;
    if(le <= mid) res = Query(ls(x),le,ri) ; if(mid < ri) res = res*Query(rs(x),le,ri)%MOD ; return res ;
}
#undef mid
void Solve(int le,int ri)
{
    if(le > ri) return ; int mid = le+ri>>1 ; FOR(i,le,ri,1) qu[i].clear(),dan[i].clear() ;
    FOR(i,le,mid-1,1) FOR(j,mid+1,ri,1) if(p[i][j].size())
        for(auto [l,r,id]:p[i][j]) qu[i].pb({l,r,id}),qu[j].pb({l,r,id}) ;
    FOR(i,le,mid,1) if(p[i][mid].size())
        for(auto [l,r,id]:p[i][mid]) qu[i].pb({l,r,id}) ;
    FOR(i,mid+1,ri,1) if(p[mid][i].size())
        for(auto [l,r,id]:p[mid][i]) dan[i].pb({l,r,id}) ;
    FOR(i,1,m,1) sum[i] = 1 ;
    ROF(i,mid,le,1) 
    {
        FOR(j,1,m,1) sum[j] = sum[j]*a[i][j]%MOD ; Build(1,1,m) ;
        for(auto [l,r,id]:qu[i]) ans[id] = ans[id]*Query(1,l,r)%MOD ;
    }
    FOR(i,1,m,1) sum[i] = 1 ;
    FOR(i,mid+1,ri,1) 
    {
        FOR(j,1,m,1) sum[j] = sum[j]*a[i][j]%MOD ; Build(1,1,m) ;
        for(auto [l,r,id]:qu[i]) ans[id] = ans[id]*Query(1,l,r)%MOD ;
    }
    FOR(i,1,m,1) sum[i] = 1 ;
    FOR(i,mid,ri,1)
    {
        FOR(j,1,m,1) sum[j] = sum[j]*a[i][j]%MOD ; Build(1,1,m) ;
        for(auto [l,r,id]:dan[i]) ans[id] = Query(1,l,r) ;
    }
    Solve(le,mid-1),Solve(mid+1,ri) ;
}
signed main()
{
// cerr<<(double)(&s_gnd-&S_GND)/1024.0/1024.0 ;
	freopen("tsuki.in","r",stdin) ;
	freopen("tsuki.out","w",stdout) ;
    read(n),read(m),read(MOD) ;
    FOR(i,1,n,1) FOR(j,1,m,1) read(a[i][j]) ;
    int q ; read(q) ; FOR(i,1,q,1)
    {
        int xx,yy,XX,YY ; read(xx),read(yy),read(XX),read(YY) ;
        p[xx][XX].pb({yy,YY,i}),ans[i] = 1 ;
    }
    Solve(1,n) ; 
    // FOR(i,1,q,1) print(ans[i]) ; enter ;
    FOR(i,1,q,1) rl = (rl+(i^ans[i]))%147744151 ; print(rl) ; cerr<<clock()/1000.0 ;
    return 0 ;
}